// webrequest.go
package webrequest

import (
	"encoding/json"
	"errors"

	//	"fmt"
	"io"
	"net/http"
	"strconv"
	"time"

	//	"swim/serviceclient"
	"swim/contain"
	"swim/etc"
	"swim/lang"
	"swim/redisclient"
	"swim/request"
	"swim/swdb"
	"swim/util"
)

type Page struct {
	Sid      string
	Peer_sid string
	Nickname string
	Card     string
}

func ClientMsgLoop(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		query := r.URL.Query()
		groupAccount := query.Get("s") //得到服务组名称
		slang := query.Get("lang")     //得到语言标识
		if !lang.CheckLang(slang) {
			return
		}
		if groupAccount == "" {
			util.WriteErrorMsg(w, "input_error",
				"service_group_not_empty", slang)
			return
		} else {
			if swdb.IsExistGroup(groupAccount) {
				//找到对应的客服人员没有找到则出现留言界面
				sClient, bFind := contain.G_servieceGroup.FindOnlineService(groupAccount)
				if bFind {
					ip := r.Header.Get("Remote_addr")
					if ip == "" {
						ip = r.RemoteAddr
					}
					iCount, gErr := getIpCount(ip)
					if gErr != nil {
						setIpCount(ip, 1)
					} else {
						if iCount > etc.SwImConfiger.OneIpMax {
							util.WriteErrorMsg(w, "service_error",
								"too_much_user_run", slang)
							return
						}
						iCount++
						setIpCount(ip, iCount)
					}
					//增加服务端SID
					newSession := contain.G_ServiceSessionPool.AddSession(sClient,
						etc.S_CTYPE_WEB, w, r.RemoteAddr)

					if newSession != nil {
						wClient := contain.G_webClients.AddClient(w, r.RemoteAddr)
						if wClient != nil {
							sClient.AddSession(wClient.Id, newSession.Sid)
							locals := make(map[string]interface{})
							locals["nickname"] = sClient.User.Name
							locals["cardflag"] = "0"
							locals["peer_sid"] = newSession.Sid //服务人员SID
							locals["sid"] = wClient.Id          //当前匿名WEB客户端的SID
							locals["card"] = "职位:" + sClient.User.Offer + "</br></br>电话:" + sClient.User.Phone
							locals["ctype"] = etc.S_CTYPE_WEB
							locals["send_url"] = "/msg/"
							locals["get_url"] = "/msg/"
							locals["down_plug_url"] = "/static/plugin/setup_imgsvr.exe"
							util.RenderHtml(w, slang+"message", locals)
							strFirstHint, _ := swdb.QeerytGroupHint(groupAccount)
							if len(strFirstHint) > 0 {
								var webMsg request.WebMsg
								webMsg.Name = sClient.User.Name
								webMsg.Msg = strFirstHint
								wClient.WriteMsg(webMsg)
							}
						} else {
							//服务器超限额 自动转移到另外的机器
							util.WriteErrorMsg(w, "service_error",
								"too_much_user_run", slang)
						}

					}

				} else { //出现留言界面
					urlString := etc.SwImConfiger.OfflineMsgUrl + "?group=" + groupAccount
					if slang != "" {
						urlString = urlString + "&lang=" + slang
					}
					http.Redirect(w, r, urlString, http.StatusFound)
				}

			} else {
				util.WriteErrorMsg(w, "input_error",
					"service_group_not_exist", slang)
				return
			}

		}
	} else {
		act := r.FormValue("act")
		switch act {
		case "sendmsg":
			onSendMsg(w, r)
		case "getmsg":
			onGetMsg(w, r)
		case "remove":
			onRemove(w, r)
		}
	}
}

func onRemove(w http.ResponseWriter, r *http.Request) {
	sid := r.FormValue("sid")           //自身ID
	peer_sid := r.FormValue("peer_sid") //对方ID
	if !checkSID(sid) || !checkSID(peer_sid) {
		return
	}
	contain.G_webClients.RemoveClient(sid)
	s, bFind := contain.G_ServiceSessionPool.FindSessionBySid(peer_sid)
	if bFind {
		s.UserService.RemoveSession(sid)
	}
	reStr := "{\"r\":\"1\"}"
	io.WriteString(w, reStr)
}

func onGetMsg(w http.ResponseWriter, r *http.Request) {
	sid := r.FormValue("sid") //自身ID
	if !checkSID(sid) {
		return
	}
	cWeb, bFindWeb := contain.G_webClients.FindClient(sid)
	if bFindWeb {
		webMsg, err := cWeb.GetMsg()
		if err == nil {
			msg, sErr := json.Marshal(webMsg)
			if sErr == nil {
				io.WriteString(w, string(msg))
			}
		}
	}
}

func onSendMsg(w http.ResponseWriter, r *http.Request) {
	sid := r.FormValue("sid")           //自身ID
	peer_sid := r.FormValue("peer_sid") //对方ID
	msg := r.FormValue("msg")
	if !checkSID(sid) || !checkSID(peer_sid) {
		return
	}
	if len(msg) > 2*etc.MAX_MSG_LEN {
		return
	}
	var webMsg request.WebMsg
	webMsg.Msg = msg
	cWeb, bFindWeb := contain.G_webClients.FindClient(sid)
	if bFindWeb {
		webMsg.Name = cWeb.TmpName
	}
	sService, bFind := contain.G_ServiceSessionPool.FindSessionBySid(peer_sid)
	if bFind {
		sService.WriteMsg(webMsg)
		swdb.WriteMsgLog(etc.S_SAY_C2S, util.GetIpFromIPort(r.RemoteAddr), sid, webMsg.Msg,
			"", sService.UserService.User.Account, sid)
		reStr := "{\"r\":\"1\"}"
		io.WriteString(w, reStr)
	}
}

func checkSID(sid string) bool {
	if sid == "" || len(sid) > etc.MAX_SID_LEN {
		return false
	}
	return true
}

func setIpCount(ip string, iCount int) error {

	key := util.GetIpFromIPort(ip) + "_webc"

	rErr := redisclient.G_cache.Put(key, iCount, 300*time.Second)

	return rErr
}

func getIpCount(ip string) (int, error) {

	var iCount int
	var err error
	key := util.GetIpFromIPort(ip) + "_webc"
	v := redisclient.G_cache.Get(key)

	value, ok := util.String(v)
	if !ok {
		err = errors.New("It's not ok for type int")
	} else {
		i, cErr := strconv.Atoi(value)
		if cErr == nil {
			iCount = i
		} else {
			err = cErr
		}
	}
	return iCount, err
}
